package utilities.event;

import java.util.*;

import hibernate.HibernateInitializer;
import hibernate.billStream.Bill;
import hibernate.billStream.ConcreteBill;
import hibernate.billStream.MergedBill;
import hibernate.clientAccount.ClientBasicInfo;
import hibernate.clientAccount.ClientBillState;
import hibernate.clientAccount.ClientVIPInfo;
import hibernate.clientAccount.SingleClient;
import hibernate.clientAccount.VIPClient;
import hibernate.hibernateInterface.BillSystemHibernateInterface;
import hibernate.hibernateInterface.ClientSystemHibernateInterface;
import hibernate.hibernateInterface.RoomSystemHibernateInterface;
import hibernate.p.DocType;
import hibernate.roomSystem.Room;
import hibernate.roomSystem.RoomState;
import hibernate.roomSystem.SizeAndFacilities;

import org.hibernate.*;
import org.hibernate.Session;
import org.hibernate.cfg.*;
import org.zkoss.zk.ui.event.*;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zul.*;
import org.zkoss.zk.ui.*;

public class CheckInListener 
implements EventListener{
	
	public void onEvent(Event e){
		String action=e.getTarget().getPage().getAttribute("ACTION").toString();
		if(action.equals("DECIDEADD"))
			decideAdd(e.getTarget());
		else if(action.equals("DELETE"))
			deleteCol((List)e.getTarget().getPage().getAttribute("SELCOL"),e.getTarget());
		else if(action.equals("SELECT"))
			selectClient(e.getTarget());
	}
	
	private void selectClient(Component comp){
		Session session=null;
		try{
			session=HibernateInitializer.getSession();
			Transaction trans=session.beginTransaction();
			
			List ret=new LinkedList();
			List raw=ClientSystemHibernateInterface.getAllSingleClients(session);
			Iterator itr=raw.iterator();
			while(itr.hasNext()){
				SingleClient client=(SingleClient)itr.next();
				List col=new LinkedList();
				col.add(client.getId());
				col.add(client.getPersonalInfo().getFirstName());
				String type=client.getPersonalInfo().getDocType();
				col.add(type.equals("ID_CARD") ? "身份证" : type.equals("MILITANT_CARD") ? "军人证" : "学生证");
				col.add(client.getPersonalInfo().getDocNumber());
				col.add(client.getPersonalInfo().getBirthday().getYear()+"-"+
						client.getPersonalInfo().getBirthday().getMonth()+"-"+
						client.getPersonalInfo().getBirthday().getDate());
				col.add(client.getPersonalInfo().getSex() == true ? "男" : "女");
				col.add(client.getPersonalInfo().getConcreteAddress().getNation());
				col.add(client.getPersonalInfo().getConcreteAddress().getProvince());
				col.add(client.getPersonalInfo().getConcreteAddress().getCityAddress());
				col.add(client.getPersonalInfo().getConceteTel1().getNumber());
				col.add(client.getNote());
				col.add((client instanceof VIPClient) ? "是" : "否");
				ret.add(col);
			}
			
			comp.getPage().setAttribute("CLIENT_INFO",ret);
		
			trans.commit();
			session.close();
		}catch(Exception e){
			try{new Messagebox().show("数据库同步失败");}catch(Exception messageExp){}
		}finally{
			if(session != null && session.isOpen())
				session.close();
		}
	}
	
	private void deleteCol(List data,Component comp){
		try{
			if(!(data.get(0) instanceof Listcell) ||
				((Listcell)data.get(0)).getLabel() == null ||
				((Listcell)data.get(0)).getLabel().equals("ID")){
				try{new Messagebox().show("数据库中无此开房信息");}catch(Exception e){}
				comp.getPage().setAttribute("IS_DELETED",null);
				return;
			}
			
			Session session=HibernateInitializer.getSession();
			Transaction trans=session.beginTransaction();
		
			Room r=null;
			try{
				r=RoomSystemHibernateInterface.getRoomByID(new Long(((Listcell)data.get(0)).getLabel()),session);
			}catch(Exception e){
				try{new Messagebox().show("数据库中无此开房信息");}catch(Exception messageExp){}
				comp.getPage().setAttribute("IS_DELETED",null);
				return;
			}

			ConcreteBill bill=r.getRoomState().getCurrentBill();
			if(bill == null || bill.getCurrentClient() == null){
				try{new Messagebox().show("数据库中无此记录相关的用户信息");}catch(Exception messageExp){}
				comp.getPage().setAttribute("IS_DELETED",null);
				return;
			}

			boolean isCheckOutNeeded=false;
			SingleClient client=bill.getCurrentClient();
			if(client.getClientBillState().getCurrentBill() instanceof MergedBill)
				isCheckOutNeeded=true;
			
			//reset the room,delete the bill
			r.getRoomState().setStates("EMPTY");
			r.getRoomState().setCurrentBill(null);
			System.out.println("1");
			session.update(r);
			System.out.println("2");
			ArrayList deleteCandidate=new ArrayList();
			MergedBill parent=bill.getGroup();
			while(parent != null){
				parent=(MergedBill)session.get(MergedBill.class,parent.getId());
				deleteCandidate.add(parent);
				parent=parent.getGroup();
			}
			
			ArrayList delList=new ArrayList();
			System.out.println("3");
			//session.delete(bill);
			delList.add(bill);
			System.out.println("4");
			Iterator deleteBillItr=deleteCandidate.iterator();
			while(deleteBillItr.hasNext()){
				//session.delete(deleteBillItr.next());
				delList.add(deleteBillItr.next());
			}
			
			if(!BillSystemHibernateInterface.isClientInHotel(client, session)){
				client.setIsCurrentInHotel(false);
				client.getClientBillState().setCurrentBill(null);
				client.getClientBillState().setDeposite(0.0);
				client.getClientBillState().setIsBillAccountOwner(false);
				System.out.println("5");
				session.update(client);
				System.out.println("6");
				if(isCheckOutNeeded)
					try{new Messagebox().show("该客人需要结帐,请操作后转至结帐页面");}catch(Exception e){}
			}
			System.out.println("7");
			trans.commit();
			session.close();
			
			session=HibernateInitializer.getSession();
			trans=session.beginTransaction();
			for(int i=0;i < delList.size();i++){
				Bill b=((Bill)delList.get(i));
				b=(Bill)session.get(b.getClass(),b.getId());
				b.setCurrentClientDeposite(null);
				b.setCurrentCorporationDeposite(null);
				b.setGroup(null);
				
				if(b instanceof ConcreteBill){
					ConcreteBill bb=(ConcreteBill)b;
					bb.setAssociatedRoom(null);
					bb.setCurrentClient(client);
				}
				
				session.delete(b);
			}
			trans.commit();
			session.close();
			
			comp.getPage().setAttribute("IS_DELETED",true);
		}catch(Exception e){
			e.printStackTrace();
			comp.getPage().setAttribute("IS_DELETED",null);
			try{new Messagebox().show("数据库同步失败");}catch(Exception messageExp){}
		}
	}
	
	private String mapType(int index){
		if(index == 0)
			return "SINGLE";
		if(index == 1)
			return "DOUBLE";
		if(index == 2)
			return "TRIPLE";
		if(index == 3)
			return "QUAD";
		if(index == 4)
			return "SUITE";
		if(index == 5)
			return "STANDARD";
			return "TSU";
	}
	
	private void decideAdd(Component comp){
		org.hibernate.Session session=null;
		try{
			//fetch room reserve info
			String roomType=mapType((Integer)comp.getPage().getAttribute("ROOMTYPE"));
			int number=(Integer)comp.getPage().getAttribute("ROOM_NUMBER");
			Boolean isPart=(Boolean)comp.getPage().getAttribute("IS_PART");
			
			//fetch client info
			String name=comp.getPage().getAttribute("NAME").toString();
			String telNumber=comp.getPage().getAttribute("TELNUMBER").toString();
			DocType docType=DocType.get(comp.getPage().getAttribute("DOCTYPE").toString());
			String docNumber=comp.getPage().getAttribute("DOCNUMBER").toString();
			Date birthday=(Date)comp.getPage().getAttribute("BIRTHDAY");
			Boolean sex=(Boolean)comp.getPage().getAttribute("SEX");
			String region=comp.getPage().getAttribute("REGION").toString();
			String province=comp.getPage().getAttribute("PROVINCE").toString();
			String address=comp.getPage().getAttribute("ADDRESS").toString();
			String note=comp.getPage().getAttribute("NOTE").toString();
			Double deposite=(Double)comp.getPage().getAttribute("DEPOSITE");
			String payNote=comp.getPage().getAttribute("PAYNOTE").toString();
			Boolean vip=(Boolean)comp.getPage().getAttribute("VIP");
			Boolean doDeposite=(Boolean)comp.getPage().getAttribute("RECEIVEDEPOSITE");
			String billNumber=comp.getPage().getAttribute("BILLNUMBER").toString();
			
			//begin talk with db
			session=HibernateInitializer.getSession();
			Transaction trans=session.beginTransaction();
			
			//firstly we find client with a given name
			SingleClient client=null;
			try{
				client=ClientSystemHibernateInterface.getSingleClientByDoc(docType, docNumber, session);
			}catch(Exception excep){
				try{
					new Messagebox().show("存在证件类型和号码相同的客人,数据库错误");
				}catch(Exception e){}
			}
			
			if(client != null){
				try{
					new Messagebox().show("证件号码相同的客人存在,自动选择该客人");
				}catch(Exception e){}
			}else{
				if(vip)
					client=new VIPClient();
				else 
					client=new SingleClient();
				client.setClientBillState(new ClientBillState());
				client.setPersonalInfo(new ClientBasicInfo());
			}
			
			client.getClientBillState().setCurrentBill(null);
			client.getClientBillState().setDeposite(doDeposite ? deposite : 0.0);
			client.getClientBillState().setIsBillAccountOwner(false);
			client.setIsCurrentInHotel(false);
			client.setIsGroupMember(false);
			client.setNote(note);
			client.setOperator(null);
			client.getPersonalInfo().setClient(client);
			client.getPersonalInfo().setAddress(address);
			client.getPersonalInfo().setAge((int)(new Date().getTime()-birthday.getTime())/86400000);
			client.getPersonalInfo().setBirthday(birthday);
			client.getPersonalInfo().setDocNumber(docNumber);
			client.getPersonalInfo().setDocType(docType.toString());
			client.getPersonalInfo().setEmail(null);
			client.getPersonalInfo().setFirstName(name);
			client.getPersonalInfo().setMiddleName(null);
			client.getPersonalInfo().setLastName(null);
			client.getPersonalInfo().setRegisterDate(new Date());
			client.getPersonalInfo().setSex(sex);
			client.getPersonalInfo().setTelNumber1(telNumber);
			
			if(client instanceof VIPClient){
				((VIPClient)client).setVipInfo(new ClientVIPInfo());
				((VIPClient)client).getVipInfo().setClient((VIPClient)client);
				((VIPClient) client).getVipInfo().setVipLevel("NORMAL");
			}
			session.saveOrUpdate(client);
			
			trans.commit();
			session.close();
			
			session=HibernateInitializer.getSession();
			trans=session.beginTransaction();
			
			client=(SingleClient)session.get(SingleClient.class,client.getId());
			
			List rooms=null;
			try{
				rooms=RoomSystemHibernateInterface.
				getRoomsBySAFAndState(isPart,SizeAndFacilities.getInstance(roomType),RoomState.ConcreteType.empty,session);
			}catch(Exception e){e.printStackTrace();}
			if(rooms == null || rooms.size() < number){
				try{new Messagebox().show("没有足够房间");}catch(Exception e){}
				return;
			}
			
			MergedBill parentBill=null;
			if(number > 1){
				parentBill=new MergedBill();
				parentBill.setBills(new HashSet());
				parentBill.setBillState("ACTIVE");
				parentBill.setGroup(null);
				parentBill.setCurrentClientDeposite(client);
				parentBill.setCurrentCorporationDeposite(null);
				parentBill.setOperator(null);
				parentBill.setPrice(0.0);
				parentBill.setTimeCreate(new Date());
				parentBill.setBillNumber(billNumber);
			}
			session.save(parentBill);
			
			List ret=new LinkedList();
			for(int i=0;i < number;i++){
				//update db
				Room r=(Room)rooms.get(i);
				r.getRoomState().setStates(RoomState.ConcreteType.occupied.toString());
				r.getRoomState().setCurrentClient(client);
				
				ConcreteBill bill=new ConcreteBill();
				r.getRoomState().setCurrentBill(bill);
				bill.setBillNumber(billNumber);
				bill.setTimeCreate(new Date());
				bill.setOperator(null);
				bill.setAccommodatingList(new HashSet());
				bill.setServiceList(new HashSet());
				bill.setBillState("ACTIVE");
				bill.setCountByHour(isPart);
				
				bill.setCurrentClient(client);
				client.setIsCurrentInHotel(true);
				client.setIsGroupMember(false);
				client.getClientBillState().setCurrentBill(parentBill);
				
				bill.setCurrentClientDeposite(client);
				bill.setAssociatedRoom(r);
				bill.setGroup(parentBill);
				bill.setCurrentCorporationDeposite(null);
				bill.setPrice(0.0);
				bill.setTimePay(null);
				if(parentBill != null)
					parentBill.getBills().add(parentBill);
				session.saveOrUpdate(r);
				session.saveOrUpdate(bill);
				session.saveOrUpdate(client);
				
				//feed data to show in client side
				List col=new LinkedList();
				ret.add(col);
				col.add(r.getId());
				col.add(r.getRoomNumber());
				col.add(isPart ? r.getRoomType().getPricePerHour() : r.getRoomType().getPricePerDay());
			}
			comp.getPage().setAttribute("ROOM_DATA",ret);
	
			trans.commit();
			session.close();
			
		}catch(Exception e){
			e.printStackTrace();
			try{new Messagebox().show("数据库同步失败");}catch(Exception me){}
		}finally{
			if(session != null && session.isOpen())
				session.close();
		}
	}
}
